﻿using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Globalization;
using AudiPyme.BLL;
using System.IO;
using System.Data;
using AudiPyme.DAL;
using System.Data.Linq.SqlClient;

namespace AudiPyme.UI
{

    public partial class RelacionesAddTipActAmenCritRies : System.Web.UI.Page
    {
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                try
                {
                    int IdEmpresa = DatosEmpresa();
                    if (IdEmpresa != -1)
                    {
                        ModeloContainer agenteBD = new ModeloContainer();
                        //Número de relaciones seleccionadas actualmente
                        int nControlesOn = 0;
                        //Cogemos el número total de Tipos Activos, Amenazas y Criterios de Riesgo para dimensionar las estructuras acordes a ellas
                        int numeroTiposActivo = TiposActivosFactory.TiposActivosTotales();
                        int numeroAmenazas = AmenazasFactory.AmenazasTotales();
                        int numeroCriterios = CriteriosRiesgoFactory.CriteriosRiesgoTotales();
                        //Lista de enteros que almacena que relación Tipo Activo-Amenaza-Criterio de Riesgo ha sido seleccionada
                        int[, ,] Contador = new int[numeroTiposActivo, numeroAmenazas, numeroCriterios];
                        //Inicializamos la matriz
                        for (int i = 0; i < numeroTiposActivo; i++)
                        {
                            for (int j = 0; j < numeroAmenazas; j++)
                            {
                                for (int k = 0; k < numeroCriterios; k++)
                                {
                                    Contador[i, j, k] = 0;
                                }
                            }
                        }
                        String OpcionFiltro = RblFiltro.SelectedValue;
                        String TextoBuscar = TxtFiltro.Text;
                        LlenaGridView(OpcionFiltro, TextoBuscar);
                        //Inicializamos la estructura que va a almacenar los estados de las relaciones
                        TipActAmenCritRiesCheck[, ,] CheckList = new TipActAmenCritRiesCheck[numeroTiposActivo, numeroAmenazas, numeroCriterios];
                        for (int i = 0; i < numeroTiposActivo; i++)
                        {
                            for (int j = 0; j < numeroAmenazas; j++)
                            {
                                for (int k = 0; k < numeroCriterios; k++)
                                {
                                    CheckList[i, j, k] = new TipActAmenCritRiesCheck();
                                }
                            }
                        }
                        //Guardamos en variables de sesión
                        Session["CheckList"] = CheckList;
                        Session["Contador"] = Contador;
                        Session["nControlesOn"] = nControlesOn;
                    }
                    else
                    {
                        MuestraMensaje("No hay una empresa asociada al usuario");
                        PnlOpciones.Visible = false;
                    }
                }
                catch (Exception e1)
                {
                    e1.ToString();
                    MuestraMensaje("Error al cargar la página");
                }
            }
        }

        //Método que se ejecuta al evento de cliquear uno de los checkbox de cualquier relación de la tabla
        protected void CheckBox_Changued(Object sender, EventArgs e)
        {
            try
            {
                int IdEmpresa = DatosEmpresa();
                if (IdEmpresa != -1)
                {
                    //Recuperamos las variables de sesión
                    //Recogemos el valor de las relaciones seleccionadas en las otras paginas del GridView
                    //con la variable de sesión nControlesOn
                    int nControlesOn = (int)Session["nControlesOn"];
                    int[, ,] Contador = (int[, ,])Session["Contador"];
                    TipActAmenCritRiesCheck[, ,] CheckList = (TipActAmenCritRiesCheck[, ,])Session["Checklist"];
                    //Recorremos la página que el gridview muestra
                    foreach (GridViewRow row in GridView1.Rows)
                    {
                        //Recogemos el control CheckBox de cada fila del gridview
                        CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                        //Recogemos el Id del Tipo de Activo, el Id de la Amenaza y el Id del Criterio de Riesgo de cada fila
                        int IdTipoActivo;
                        int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdTipoActivo);
                        int IdAmenaza;
                        int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdAmenaza);
                        int IdCritRiesgo;
                        int.TryParse(GridView1.Rows[row.RowIndex].Cells[4].Text, out IdCritRiesgo);
                        //Si es la primera vez que se elige esa relación, aumentamos el contador
                        //y marcamos que esa relación ya está elegida
                        if (Chk.Checked == true && Contador[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] == 0)
                        {
                            if (nControlesOn == 0)
                            {
                                BtnInsertar.Enabled = true;
                            }
                            Contador[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] = 1;
                            TipActAmenCritRiesCheck RelacionCheck = new TipActAmenCritRiesCheck(IdEmpresa, IdTipoActivo, IdAmenaza, IdCritRiesgo, true);
                            CheckList[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] = RelacionCheck;
                            CheckList[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1].ValorCheck = true;
                            nControlesOn++;
                        }
                        //Sino marcamos que la relación no está elegida y actualizamos estructuras
                        else if (Chk.Checked == false && Contador[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] == 1)
                        {
                            Contador[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] = 0;
                            CheckList[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1].ValorCheck = false;
                            nControlesOn--;
                            if (nControlesOn == 0)
                            {
                                BtnInsertar.Enabled = false;
                            }
                        }

                    }
                    //Si estamos en la opción de elementos Seleccionados, actualizamos el gridview
                    String OpcionFiltro = RblFiltro.SelectedValue;
                    if (OpcionFiltro.Equals("RelacSelec"))
                    {
                        GridViewRelacionesSeleccionadas();
                    }
                    //Actualizamos el número de controles elegidos en el label
                    LblControl.Text = nControlesOn.ToString();
                    //Guardamos en la variable de sesión
                    Session["nControlesOn"] = nControlesOn;
                }
            }
            catch (Exception e1)
            {
                MuestraMensaje("Error al hacer click en el elemento de la tabla");
                e1.ToString();
            }

        }

        protected void GridView1_PageIndexChanging(object sender, GridViewPageEventArgs e)
        {
            int IdEmpresa = DatosEmpresa();
            if (IdEmpresa != -1)
            {
                try
                {
                    //Recogemos el array que contiene las relaciones que han sido elegidas 
                    int[, ,] Contador = (int[, ,])Session["Contador"];
                    //Recogemos el array tipado con el valor de las relaciones que han sido elegidas
                    TipActAmenCritRiesCheck[, ,] CheckList = (TipActAmenCritRiesCheck[, ,])Session["Checklist"];
                    //Recorremos el Gridview antes de cambiar de página
                    foreach (GridViewRow row in GridView1.Rows)
                    {
                        //Recogemos el control CheckBox de cada fila
                        CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                        //Si está seleccionado
                        if (Chk.Checked == true)
                        {
                            //Recogemos el IdTipoActivo, IdAmenaza y el IdCriterioRiesgo de la fila
                            int IdTipoActivo;
                            int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdTipoActivo);
                            int IdAmenaza;
                            int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdAmenaza);
                            int IdCritRiesgo;
                            int.TryParse(GridView1.Rows[row.RowIndex].Cells[4].Text, out IdCritRiesgo);
                            //Actualizamos el valor de contador
                            Contador[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] = 1;
                            //Creamos el objeto AmenContrCheck con los valores y lo insertamos en la lista
                            TipActAmenCritRiesCheck RelacionCheck = new TipActAmenCritRiesCheck(IdEmpresa, IdTipoActivo, IdAmenaza, IdCritRiesgo, true);
                            CheckList[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] = RelacionCheck;
                        }
                        //Si no está seleccionado
                        if (Chk.Checked == false)
                        {
                            //Recogemos el IdTipoActivo, IdAmenaza y el IdCriterioRiesgo de la fila
                            int IdTipoActivo;
                            int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdTipoActivo);
                            int IdAmenaza;
                            int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdAmenaza);
                            int IdCritRiesgo;
                            int.TryParse(GridView1.Rows[row.RowIndex].Cells[4].Text, out IdCritRiesgo);
                            //Actualizamos el valor de contador
                            Contador[IdTipoActivo - 1, IdAmenaza - 1, IdCritRiesgo - 1] = 0;
                            //Creamos el objeto TipActAmenCritRiesCheck con los valores y lo insertamos en la lista
                            TipActAmenCritRiesCheck RelacionChequeada = new TipActAmenCritRiesCheck(IdEmpresa, IdTipoActivo, IdAmenaza, IdCritRiesgo, false);
                        }
                    }
                    //Actualizamos la variable de sesión
                    Session["Contador"] = Contador;
                    this.GridView1.PageIndex = e.NewPageIndex;
                    Session["CheckList"] = CheckList;
                    ModeloContainer agenteBD = new ModeloContainer();
                    String OpcionFiltro = RblFiltro.SelectedValue;
                    if (OpcionFiltro.Equals("RelacSelec"))
                    {
                        GridViewRelacionesSeleccionadas();
                    }
                    else
                    {
                        String TextoBuscar = TxtFiltro.Text;
                        LlenaGridView(OpcionFiltro, TextoBuscar);
                        ActualizaCheckListTabla();
                    }
                }
                catch (Exception e1)
                {
                    e1.ToString();
                    MuestraMensaje("Error al actualizar la tabla con los elementos seleccionados");
                }
            }
        }

        //Evento que se ejecuta al pulsar el boton Insertar
        protected void BtnInsertar_Click(object sender, EventArgs e)
        {
            int IdEmpresa = DatosEmpresa();
            ModeloContainer agenteBD = new ModeloContainer();
            if (IdEmpresa != -1)
            {
                try
                {
                    //Recogemos la estructura con el valor de sesión
                    TipActAmenCritRiesCheck[, ,] CheckList = (TipActAmenCritRiesCheck[, ,])Session["Checklist"];
                    int numeroTiposActivo = TiposActivosFactory.TiposActivosTotales();
                    int numeroAmenazas = AmenazasFactory.AmenazasTotales();
                    int numeroCriterios = CriteriosRiesgoFactory.CriteriosRiesgoTotales();
                    for (int i = 0; i < numeroTiposActivo; i++)
                    {
                        for (int j = 0; j < numeroAmenazas; j++)
                        {
                            for (int k = 0; k < numeroCriterios; k++)
                            {
                                if (CheckList[i, j, k].ValorCheck == true)
                                {
                                    //Insertamos la instancia en la BD
                                    int IdTipoActivo = CheckList[i, j, k].IdTipoActivo;
                                    int IdAmenaza = CheckList[i, j, k].IdAmenaza;
                                    int IdCriterioRiesgo = CheckList[i, j, k].IdCriterioRiesgo;
                                    InstanciaTiposActivosAmenazasCriteriosRiesgoFactory.InsertarInstanciaTipActAmenCrit(IdEmpresa, IdTipoActivo, IdAmenaza, IdCriterioRiesgo);
                                }
                            }
                        }
                    }
                    agenteBD.SaveChanges();
                    MuestraMensajeRedirige("Las relaciones se han insertado correctamente", "RelacionesPrincipal");
                }
                catch (Exception e1)
                {
                    e1.ToString();
                    MuestraMensaje("Error al insertar las relaciones");
                }
            }
        }

        private void MuestraMensajeRedirige(string Mensaje, string Pagina)
        {
            StringBuilder SB = new StringBuilder();
            SB.Append("alert('");
            SB.Append(Mensaje.Replace("\n", "\\n").Replace("\r", "").Replace("'", "\\'"));
            SB.Append("');");
            SB.Append("var vers = navigator.appVersion;if(vers.indexOf('MSIE 7.0') != -1) { window.location='" + Pagina + ".aspx';} else{ window.location='" + Pagina + ".aspx'; }");
            ScriptManager.RegisterStartupScript(this, this.GetType(), "Success", SB.ToString(), true);
        }


        private int DatosEmpresa()
        {
            try
            {
                int IdEmpresa = -1;
                String nombreUsuario = (String)Session["nombreUsuario"];
                IdEmpresa = UsuariosFactory.EmpresaUsuario(nombreUsuario);
                if (IdEmpresa == 0)
                {
                    MuestraMensaje("El usuario " + nombreUsuario + " no esta asociado a una empresa");
                    return -1;
                }
                else
                {
                    return IdEmpresa;
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                Session.Abandon();
                MuestraMensajeRedirige("Error al recoger la variable de sesión. La aplicación se cerrará por motivos de seguridad", "InicioSesion");
                return -1;
            }
        }

        private void MuestraMensaje(string Mensaje)
        {
            StringBuilder SB = new StringBuilder();
            SB.Append("alert('");
            SB.Append(Mensaje.Replace("\n", "\\n").Replace("\r", "").Replace("'", "\\'"));
            SB.Append("');");
            ScriptManager.RegisterStartupScript(this, this.GetType(), "Success", SB.ToString(), true);
        }

        protected void RblFiltro_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (RblFiltro.SelectedValue.Equals("RelacSelec"))
            {
                TxtFiltro.Visible = false;
                BtnBuscar.Visible = false;
                GridViewRelacionesSeleccionadas();
            }
            else
            {
                TxtFiltro.Visible = true;
                BtnBuscar.Visible = true;
                //Limpiamos el TextBox ya que venimos de otra opción
                TxtFiltro.Text = "";
                String OpcionFiltro = RblFiltro.SelectedValue;
                String TextoBuscar = TxtFiltro.Text;
                LlenaGridView(OpcionFiltro, TextoBuscar);
                ActualizaCheckListTabla();
            }
        }

        private void GridViewRelacionesSeleccionadas()
        {
            try
            {
                ModeloContainer agenteBD = new ModeloContainer();
                int IdEmpresa = DatosEmpresa();
                //Recogemos la estructura con el valor de sesión
                TipActAmenCritRiesCheck[, ,] CheckList = (TipActAmenCritRiesCheck[, ,])Session["Checklist"];
                int numeroTiposActivo = TiposActivosFactory.TiposActivosTotales();
                int numeroAmenazas = AmenazasFactory.AmenazasTotales();
                int numeroCriterios = CriteriosRiesgoFactory.CriteriosRiesgoTotales();
                List<InstanciaTipActAmenCritTabla> LRelacionesSelec = new List<InstanciaTipActAmenCritTabla>();
                for (int i = 0; i < numeroTiposActivo; i++)
                {
                    for (int j = 0; j < numeroAmenazas; j++)
                    {
                        for (int k = 0; k < numeroCriterios; k++)
                        {
                            if (CheckList[i, j, k].ValorCheck == true)
                            {
                                InstanciaTipActAmenCritTabla nuevafila = new InstanciaTipActAmenCritTabla();
                                nuevafila.TipoActivo = TiposActivosFactory.RecogeNombreTipoActivo(CheckList[i, j, k].IdTipoActivo);
                                nuevafila.Amenaza = AmenazasFactory.NombreAmenaza(CheckList[i, j, k].IdAmenaza);
                                nuevafila.CriterioRiesgo = CriteriosRiesgoFactory.NombreCriterioRiesgo(CheckList[i, j, k].IdCriterioRiesgo);
                                nuevafila.IdTipoActivo = CheckList[i, j, k].IdTipoActivo;
                                nuevafila.IdAmenaza = CheckList[i, j, k].IdAmenaza;
                                nuevafila.IdCriterioRiesgo = CheckList[i, j, k].IdCriterioRiesgo;
                                LRelacionesSelec.Add(nuevafila);
                            }
                        }
                    }
                }
                GridView1.DataSource = LRelacionesSelec;
                DataBind();
                ActualizaCheckListTabla();
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al actualizar la tabla con los elementos seleccionados");
            }
        }

        private void ActualizaCheckListTabla()
        {
            try
            {
                //Recogemos el array que contiene las relaciones que han sido elegidas 
                int[, ,] Contador = (int[, ,])Session["Contador"];
                //Recogemos el array tipado con el valor de las relaciones que han sido elegidas
                TipActAmenCritRiesCheck[, ,] CheckList = (TipActAmenCritRiesCheck[, ,])Session["Checklist"];
                //Cargamos el valor de las relaciones que estuvieran seleccionados anteriormente
                TipActAmenCritRiesCheck controlLista = new TipActAmenCritRiesCheck();
                int numeroTiposActivo = TiposActivosFactory.TiposActivosTotales();
                int numeroAmenazas = AmenazasFactory.AmenazasTotales();
                int numeroCriterios = CriteriosRiesgoFactory.CriteriosRiesgoTotales();
                for (int i = 0; i < numeroTiposActivo; i++)
                {
                    for (int j = 0; j < numeroAmenazas; j++)
                    {
                        for (int k = 0; k < numeroCriterios; k++)
                        {
                            controlLista = CheckList[i, j, k];
                            foreach (GridViewRow row in GridView1.Rows)
                            {
                                int IdTipoActivo;
                                int.TryParse(GridView1.Rows[row.RowIndex].Cells[0].Text, out IdTipoActivo);
                                int IdAmenaza;
                                int.TryParse(GridView1.Rows[row.RowIndex].Cells[2].Text, out IdAmenaza);
                                int IdCritRiesgo;
                                int.TryParse(GridView1.Rows[row.RowIndex].Cells[4].Text, out IdCritRiesgo);
                                if (IdTipoActivo == controlLista.IdTipoActivo && IdAmenaza == controlLista.IdAmenaza &&
                                    IdCritRiesgo == controlLista.IdCriterioRiesgo)
                                {
                                    CheckBox Chk = (CheckBox)row.FindControl("CheckBox1");
                                    if (controlLista.ValorCheck)
                                    {
                                        Chk.Checked = true;
                                    }
                                    else
                                    {
                                        Chk.Checked = false;
                                    }
                                }
                            }
                        }
                    }
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al mostrar los elementos seleccionados");
            }
        }

        protected void BtnBuscar_Click(object sender, EventArgs e)
        {
            String OpcionFiltro = RblFiltro.SelectedValue;
            String TextoBuscar = TxtFiltro.Text;
            LlenaGridView(OpcionFiltro, TextoBuscar);
            ActualizaCheckListTabla();
        }

        private void LlenaGridView(String OpcionFiltro, String TextoBuscar)
        {
            try
            {
                ModeloContainer agenteBD = new ModeloContainer();
                int IdEmpresa = DatosEmpresa();
                OpcionFiltro = RblFiltro.SelectedValue;
                TextoBuscar = TxtFiltro.Text;
                //Si no se ha introducido texto de búsqueda, sacamos todas las relaciones disponibles salvo las existentes en la empresa
                if (TextoBuscar.Equals("") || OpcionFiltro.Equals(""))
                {
                    List<InstanciaTipActAmenCritTabla> LRelaciones = InstanciaTipActAmenCritTabla.RecogePosiblesInstanciasIncluir(IdEmpresa);
                    GridView1.DataSource = LRelaciones;
                    DataBind();
                }
                else
                {
                    List<InstanciaTipActAmenCritTabla> LRelacionesBusqueda = new List<InstanciaTipActAmenCritTabla>();
                    switch (OpcionFiltro)
                    {
                        case "TipoActivo":
                            //Relaciones Tipo Activo-Amenaza-Criterio de Riesgo actuales de la Base de Conocimiento (Matriz) con el Filtro de TipoActivo
                            LRelacionesBusqueda = InstanciaTipActAmenCritTabla.RelacionesPorTipoActivo(IdEmpresa, TextoBuscar);
                            break;
                        case "Amenaza":
                            //Relaciones Tipo Activo-Amenaza-Criterio de Riesgo actuales de la Base de Conocimiento (Matriz) con el Filtro de Amenaza
                            LRelacionesBusqueda = InstanciaTipActAmenCritTabla.RelacionesPorAmenaza(IdEmpresa, TextoBuscar);
                            break;
                        case "CriterioRiesgo":
                            //Relaciones Tipo Activo-Amenaza-Criterio de Riesgo actuales de la Base de Conocimiento (Matriz) con el Filtro Criterio de Riesgo
                            LRelacionesBusqueda = InstanciaTipActAmenCritTabla.RelacionesPorCriterio(IdEmpresa, TextoBuscar);
                            break;
                        default:
                            MuestraMensaje("No se recogio la opcion de Filtro elegida");
                            break;
                    }
                    if (LRelacionesBusqueda.Count() == 0)
                    {
                        MuestraMensaje("No se encontraron relaciones disponibles con " + OpcionFiltro + " que contuvieran la secuencia " + TextoBuscar);
                    }
                    else
                    {
                        GridView1.DataSource = LRelacionesBusqueda;
                        DataBind();
                    }
                }
            }
            catch (Exception e1)
            {
                e1.ToString();
                MuestraMensaje("Error al actualizar los datos en la tabla");
            }
        }
    }
}